package com.lucaswangdev.controller;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.MatchMode;
import com.aliyun.oss.model.PolicyConditions;
import com.lucaswangdev.config.OssConfig;
import org.codehaus.jettison.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Date;
import java.util.Random;

@Controller
public class PostSignatureController {
    @Autowired
    private OSS ossClient;

    @Autowired
    private OssConfig ossConfig;

    @GetMapping("/get_post_signature_for_oss_upload")
    @ResponseBody
    public String generatePostSignature(@RequestParam("fileName") String fileName) {
        JSONObject response = new JSONObject();
        try {
            // 获取文件名并处理
            String processedFileName = processFileName(fileName);
            long expireEndTime = System.currentTimeMillis() + ossConfig.getExpireTime() * 1000;
            Date expiration = new Date(expireEndTime);
            PolicyConditions policyConds = new PolicyConditions();
            policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
            policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, ossConfig.getDir());
            String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
            byte[] binaryData = postPolicy.getBytes("utf-8");
            String encodedPolicy = BinaryUtil.toBase64String(binaryData);
            String postSignature = ossClient.calculatePostSignature(postPolicy);
            String endpoint = "";
            String bucketName = "";
            String preSignatureUrl = OssUtil.getPreSignUrl(ossClient, bucketName, ossConfig.getDir() + processedFileName);
            response.put("ossAccessKeyId", ossConfig.getAccessKeyId());
            response.put("policy", encodedPolicy);
            response.put("signature", postSignature);
            response.put("dir", ossConfig.getDir());
            response.put("host", ossConfig.getHost());
            response.put("preSignatureUrl", preSignatureUrl);
            response.put("key", ossConfig.getDir() + processedFileName);  // 设置上传时使用的文件路径
            System.out.println(response);
        } catch (
                OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            // 假设此方法存在
            System.out.println("HTTP Status Code: " + oe.getRawResponseError());
            System.out.println("Error Message: " + oe.getErrorMessage());
            System.out.println("Error Code:       " + oe.getErrorCode());
            System.out.println("Request ID:      " + oe.getRequestId());
            System.out.println("Host ID:           " + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message: " + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
            return response.toString();
        }
    }

    @GetMapping("/get_signature_url")
    @ResponseBody
    public String getSignatureUrl(@RequestParam("fileName") String fileName) {
        JSONObject response = new JSONObject();
        try {
            String bucketName = "oss-test1001";
            String preSignatureUrl = OssUtil.getPreSignUrl(ossClient, bucketName, ossConfig.getDir() + fileName);
            response.put("preSignatureUrl", preSignatureUrl);
            System.out.println(response);
            // return response;
        } catch (
                OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            // 假设此方法存在
            System.out.println("HTTP Status Code: " + oe.getRawResponseError());
            System.out.println("Error Message: " + oe.getErrorMessage());
            System.out.println("Error Code:       " + oe.getErrorCode());
            System.out.println("Request ID:      " + oe.getRequestId());
            System.out.println("Host ID:           " + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message: " + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
            return response.toString();
        }
    }

    // 处理文件名，去掉扩展名并加上6位随机数
    private String processFileName(String fileName) {
        // 获取文件扩展名
        String extension = fileName.substring(fileName.lastIndexOf("."));
        // 获取文件名（不包含扩展名）
        String baseName = fileName.substring(0, fileName.lastIndexOf("."));
        // 生成6位随机数
        String randomSuffix = generateRandomSuffix();
        // 处理后的文件名：文件名 + 6位随机数 + 扩展名
        return baseName + randomSuffix + extension;
    }

    // 生成6位随机数
    private String generateRandomSuffix() {
        Random random = new Random();
        int randomInt = random.nextInt(900000) + 100000;  // 生成6位数
        return String.valueOf(randomInt);
    }
}